<?php
/**
 * Model to handle companies
 *
 * @category Abovo
 * 
 * @package Abovo_Model_Company
 * 
 * @author Antti Holvikari <anttih@gmail.com>
 * 
 * @license http://opensource.org/licenses/gpl-license.php GPL
 */

/**
 * Model to handle companies
 *
 * @category Abovo
 * 
 * @package Abovo_Model_Company
 */
abstract class Abovo_Model_Company extends Abovo_Sql_Table {

    /**
     * 
     * Area name for tagging
     * 
     * @var string
     * 
     */
    protected $_area = 'companies';
    
    /**
     * 
     * Company type
     * 
     * @var string
     * 
     */
    protected $_type;
    
    /**
     * Available search keys
     *
     * @var string
     */
    protected $_search_keys = array(
        'name',
        'city',
        'postal_code',
    );
    
    /**
     * Row class to use
     *
     * @var string
     */
    protected $_row_class = 'Abovo_Model_Company_Node';
    
    /**
     * Tag model
     *
     * @var Abovo_Model_Tag
     */
    public $tags;
    
    /**
     * Saves or updates one row by it's id
     *
     * @return void
     */
    public function save($data)
    {
        // force type
        $data['type'] = $this->_type;
        
        $saved = parent::save($data);
        
        // if tags given, then refresh them
        if (! empty($data['tags'])) {
            $this->tags->refresh($data['tags'], $saved['id'], $data['handle']);
        }
        
        // return inserted/updated data
        return array_merge($data, $saved);
    }
    
    /**
     * 
     * Fetch one row by id
     * 
     * @return void
     * 
     */
    public function fetch($id)
    {
        $data = parent::fetch($id);
        
        // if node found, fetch tags
        if (count($data)) {
            $data['tags'] = $this->tags->fetchAll($id);
        }
        
        return $data;
    }
    
    /**
     * Fetches all citys and their counts
     *
     * Returns an assoc array with the city name 
     * as the key and count as value.
     * 
     * @return array Assoc array with "city name" => count
     */
    public function fetchCitys()
    {
        $sel = Solar::factory('Solar_Sql_Select');
        
        $sel->from($this->_name, array('city', 'count(city)'))
            ->group('city');
        
        return $sel->fetch('pairs');
    }
    
    /**
     * 
     * undocumented function
     * 
     * @return void
     * 
     */
    public function search($keywords)
    {
        $sel = Solar::factory('Solar_Sql_Select');
        $sel->from($this->_name, '*');
        $sel->where('type = ?', $this->_type);
        $sel->where('(name LIKE ? OR vat LIKE ?)', '%' . $keywords . '%');
        
        $res = $sel->fetch('rowset');
        
        foreach ($res as $row) {
            $row->tags = $this->tags->fetchAll($row->id);
        }
        
        return $res;
    }
    
    /**
     * 
     * Creates and returns form hints
     * 
     * @return Abovo_Form
     * 
     */
    public function form($spec = null, $cols = array())
    {
        if ($spec instanceof Abovo_Form) {
            $form = $spec;
        } else {
            $form = Solar::factory('Abovo_Form');
        }
        
        // set cols to array
        settype($cols, 'array');
        
        // if cols is empty then use this set of columns
        if (empty($cols)) {
            $cols = array(
                'name',
                'short',
                'vat',
                'ytunnus',
                'url',
                'adr',
                'postal_code',
                'city',
                'country',
                'ship_adr',
                'ship_postal_code',
                'ship_city',
                'ship_country',
                'iban',
                'bic',
                'descr',
            );
        }
        
        // load form element from table object
        $form->load(
            'Abovo_Form_Load_Table',
            $this,
            $cols,
            'company'
        );
        
        /*
        // edit textarea
        $form->elements['company[descr]']['attribs']['cols'] = 40;
        $form->elements['company[descr]']['attribs']['rows'] = 6;
        
        // get list of countrys as options
        $options = Solar::factory('Lux_Intl')->getCountryList();
        
        // these are select elements
        $form->elements['company[country]']['type']      = 'select';
        $form->elements['company[ship_country]']['type'] = 'select';
        
        // set options
        $form->elements['company[country]']['options']      = $options;
        $form->elements['company[ship_country]']['options'] = $options;
        
        $form->elements['company[iban]']['attribs']['size'] = 40;
        $form->elements['company[bic]']['attribs']['size'] = 20;
        
        // add element for tags
        $form->setElement('company[tags]', array(
            'type'  => 'text',
            'label' => $this->locale('TEXT_TAGS', 2),
            'attribs' => array(
                'size' => 40,
            ),
        ));
        */
        return $form;
    }
    
    /**
     * 
     * Creates a new select
     * 
     * @return void
     * 
     */
    protected function _newSelect()
    {
        $sel = parent::_newSelect();
        
        $sel->where('type = ?', $this->_type);
        
        return $sel;
    }
    
    /**
     * 
     * Table schema
     * 
     * @return void
     * 
     */
    protected function _setup()
    {
        // table name
        $this->_name = 'companies';
        
        $this->_col['id'] = array(
            'type'    => 'int',
            'primary' => true,
            'autoinc' => true,
            'require' => true,
        );
        
        // company type
        $this->_col['type'] = array(
            'type'    => 'varchar',
            'size'    => 10,
            'require' => true,
        );
        
        // create timestamp
        $this->_col['created'] = array(
            'type'     => 'timestamp',
            'require'  => true,
        );
        
        // update timestamp
        $this->_col['updated'] = array(
            'type'     => 'timestamp',
            'require'  => true,
        );
        
        // user id - who's added this row
        $this->_col['handle'] = array(
            'type'    => 'varchar',
            'size'    => 15,
            'require' => false,
        );
        
        // official name of the company
        $this->_col['name'] = array(
            'type'    => 'varchar',
            'size'    => 100,
            'require' => true,
        );
        
        // name detail of company i.e "Management"
        $this->_col['detail'] = array(
            'type'    => 'varchar',
            'size'    => 50,
            'require' => false,
        );
        
        // VAT number
        $this->_col['vat'] = array(
            'type'    => 'char',
            'size'    => 10,
            'require' => false,
            'filter'  => 'validateVat',
        );
        
        // finnish y-tunnus
        $this->_col['ytunnus'] = array(
            'type'    => 'char',
            'size'    => 9,
            'require' => true,
            'filter'  => 'validateYtunnus',
        );
        
        // Website URL
        $this->_col['url'] = array(
            'type'    => 'varchar',
            'size'    => 255,
            'require' => false,
            'filter'  => 'validateUri',
        );
        
        // company description
        $this->_col['descr'] = array(
            'type' => 'clob',
        );
        
        // -------------------------------
        //
        // company official address info
        //
        
        // company address
        // 'adr' is a valid hCard property
        $this->_col['adr'] = array(
            'type'    => 'varchar',
            'size'    => 100,
            'require' => true,
        );
        
        // city origin
        $this->_col['city'] = array(
            'type'    => 'varchar',
            'size'    => 50,
            'require' => true,
        );
        
        // postal code or ZIP
        $this->_col['postal_code'] = array(
            'type'    => 'varchar',
            'size'    => 5,
            'require' => true,
            'filter'  => 'validateZip',
        );
        
        // origin country
        $this->_col['country'] = array(
            'type'    => 'char',
            'size'    => 2,
            'require' => true,
            'default' => Solar::$locale->getCountryCode(),
            'filter'  => 'validateCountry',
        );
        
        // ---------------------------------
        //
        // Shipping info
        //
        
        // company address, visit address
        // 'adr' is a valid hCard property
        $this->_col['ship_adr'] = array(
            'type'    => 'varchar',
            'size'    => 100,
        );
        
        // city origin
        $this->_col['ship_city'] = array(
            'type'  => 'varchar',
            'size'  => 50,
        );
        
        // postal code or ZIP
        $this->_col['ship_postal_code'] = array(
            'type'    => 'varchar',
            'size'    => 5,
            'require' => false,
            'filter'  => 'validateZip', 
        );
        
        // origin country
        $this->_col['ship_country'] = array(
            'type'    => 'char',
            'size'    => 2,
            'require' => false,
            'filter'  => 'validateCountry',
        );
        
        // IBAN (International Bank Account Number, ISO 13616:2003)
        $this->_col['iban'] = array(
            'type'    => 'varchar',
            'size'    => 34,
            'require' => false,
            //'filter'  => 'validateIban',
        );
        
        // BIC (Bank Identifier Code, ISO 9362) 
        $this->_col['bic'] = array(
            'type'    => 'varchar',
            'size'    => 11,
            'require' => false,
            //'filter'  => 'validateBic',
        );
        
        // Make sure sql is available
        if (! Solar::isRegistered('sql')) {
            Solar::register('sql', Solar::factory('Solar_Sql'));
        }
        
        // make sure tags are available everywhere
        $this->tags = Solar::factory(
            'Abovo_Model_Tag',
            array('area' => $this->_area)
        );
    }
}
